<?php
/*
Plugin Name: My Advanced Search Plugin
Plugin URI: http://wordpress.org/
Description: Provides Set of avanced search fuctionaliies for WordPresss  
Author: Kishanthan Thangarajah
Version: 1.0
*/


// MyAdvancedSearch
// The class contains various functions for your advanced searching 

class MyAdvancedSearch
{
	//A reference to this plugin
	var $plugin = NULL;
	
	//An array of search parameters
	var $flags = array();
	 
	//MyAdvancedSearch (Constructor)
	//This function creates a new filter 'search_load' so that the plugin can call it and load class object into "$this->plugin".
	
	function MyAdvancedSearch() {
	$this->plugin = apply_filters( 'search_load', array() );
	$this->plugin->parent =& $this;
	
			
	}
	
	
	// Initialize Search
	// This function calls execute_search which is the main for this class.
		
	function initialize_search() {
		add_filter( 'template_redirect', array( &$this, 'execute_search' ) );
	}

	
	
	// Advanced Search Page
	// This function creates a "virtual" page which is used to display all the advanced search form HTML.
	//
	// 
		
	function advanced_search_page() {
		global $wp_query;
		
		// set "the loop" to nothing
		$wp_query->posts = NULL;
		
		// Create a blank "result set" for the wordpress query object
		$object = new stdClass();
		$object->post_title = __( "My Advanced Search " );
		$object->post_content = "[advsearch]";
			
		$wp_query->posts[0] = $object;	
		
		// replace the advsearch shortcode with the form, and then return the page template
		add_shortcode( 'advsearch', array( &$this, 'advanced_options_generator' ) );
		
		$template = get_page_template();
		
		if ( $template )
			include $template;
		else
			include(TEMPLATEPATH . "/index.php");

		exit;
	}
	
	
	// Advanced Link
	// This function returns a link to the advanced search page. If additonal output is passed to it then that is also returned.	
	function advanced_link( $output = '' ) {	
		// output usually comes from get_search-form
		if( !empty( $output ) )
			$html = $output;
			
		// return a link to the advanced search form
		$html .= "<small><a href='index.php?advancedsearch=1'>". __( "My Advanced Search" ) . "</a></small>";

		// search_advanced_link Allows you to edit the output of the advanced link and the search in the sidebar
		return apply_filters('search_advanced_link', $html);
	}

	// Advanced Options Generotor
	// This function generates HTML for an avanced search form (author, categories, etc). This function is outputed using a WordPress short code.
	
	function advanced_options_generator() {
	
		// Content type picker
		$option_output = "<br /> " . __( "Search:" ) ." <input type='checkbox' name='types[]' value='posts' /> " . __( "Posts" ) ."  <input type='checkbox' name='types[]' value='pages' /> " . __( "Pages" ) ." <input type='checkbox' name='types[]' value='comments' /> " . __( "Comments " ) ."<br />";
		
		// category selector (multiple choice box)
		$tax_output = "";
		
		foreach( get_object_taxonomies('post') as $taxonomy ) {
			$data = get_taxonomy( $taxonomy );
			
			if( $data->name == "category" ){
				$tax_output = "<br /> <br /> " . __( "Categories: " ) ."<br /><br />" . str_replace( "name='cat'", "name='cats[]' multiple='multiple' size='10'", wp_dropdown_categories( 'hierarchical=1&echo=0' ) );
			}
			else {
				$terms = get_terms( $data->name );
				
				if( count ( $terms ) != 0 ) {
					$tax_output .= "<br /> <br /> " . $data->label . "<br /><br /><select name='tags[]' multiple='multiple' size='10'>";
					foreach( $terms as $term ) {
						$tax_output .= "<option value='".$term->term_id."'>" . $term->name . '</option>';
					}
					$tax_output .= "</select>";
				}
			}
			
			}
			
		
		
		// Month Picker, created once and used for start and end dates
		$month_picker = "<option value=''>" . __( 'Select Month' ) . "</option> 
					<option value='1'>" . __( 'January' ) . "</option>
					<option value='2'>" . __( 'February' ) . "</option>
					<option value='3'>" . __( 'March' ) . "</option>
					<option value='4'>" . __( 'April' ) . "</option>
					<option value='5'>" . __( 'May' ) . "</option>
					<option value='6'>" . __( 'June' ) . "</option>
					<option value='7'>" . __( 'July' ) . "</option>
					<option value='8'>" . __( 'August' ) . "</option>
					<option value='9'>" . __( 'September' ) . "</option>
					<option value='10'>" . __( 'October' ) . "</option>
					<option value='11'>" . __( 'November' ) . "</option>
					<option value='12'>" . __( 'December' ) . "</option>";
		
		// Start date dropdowns
		$date_output = "<br /><br />" . __( 'From' ) . "<br /> <select name='startMonth'>{$month_picker}</select>
						<select name='startYear'> <option value=\"\">" . __( 'Select Year' ) . "</option> 
					    " . str_replace( get_option( "siteurl" ) . "/?m=", "", wp_get_archives( 'type=yearly&format=option&show_post_count=0&echo=0') ) . "</select>
						<select name='startDay'> <option value=\"\">" . __( 'Select Day' ) . "</option>";						

		for ( $i = 1; $i <= 31; $i++ ) {
			$date_output .= "<option value='{$i}'>{$i}</option>";
		}

		$date_output .= "</select>";
		
		// End date dropdowns
		$date_output .= "<br />" . __( 'to' ) . "<br /> <select name='endMonth'>{$month_picker}</select>
						<select name='endYear'> <option value=\"\">" . __( 'Select Year' ) . "</option> 
					    " . str_replace( get_option( "siteurl" ) . "/?m=", "", wp_get_archives( 'type=yearly&format=option&show_post_count=0&echo=0' ) ) . "</select>
						<select name='endDay'> <option value=\"\">" . __( 'Select Day' ) . "</option>";						

		for ( $i = 1; $i <= 31; $i++ ) {
			$date_output .= "<option value='{$i}'>{$i}</option>";
		}

		$date_output .= "</select>";
		
	
		
		// Return the final output
	//	{$author_output}
		// search_advanced Allows you to edit the output of the advanced search page
		return apply_filters( 'search_advanced', "<br /><form method='get' id='result_search_form' action='' style='text-align: left;'>
		<input type='text' value='{$this->flags['string']}' name='s' id='results' size='50' />
		{$option_output}
		{$tax_output}
		{$date_output}
		<p><input type='submit' id='searchsubmit' value='" . __( 'Adv Search' ) . "' /></p>
		</form>" );
	}

	
	// Create Flags
	// Cleans up input from the query string and sticks it in an easier to digest format for search plugins
	// Returns an array of search parameters
	
	function create_flags() {
		global $wpdb;
		// Clean up and separate the terms
		$this->flags['string'] = $wpdb->escape( $_GET['s'] );
		//echo $this->flags['string'];
		preg_match_all( '/".*?("|$)|((?<=[\\s",+])|^)[^\\s",+]+/', $this->flags['string'], $matches );
		$this->flags['terms'] = array_map( create_function( '$a', 'return trim($a, "\\"\'\\n\\r ");' ), $matches[0] );

			
		// Get the start and end dates from AdvancedSearch form
		$this->flags['startYear'] = intval( $_GET['startYear'] );
		$this->flags['startMonth'] = intval( $_GET['startMonth'] );
		$this->flags['startDay'] = intval( $_GET['startDay'] );
		
		$this->flags['endYear'] = intval( $_GET['endYear'] );
		$this->flags['endMonth'] = intval( $_GET['endMonth'] );
		$this->flags['endDay'] = intval( $_GET['endDay'] );
		
		// Get the categories from AdvancedSearch form
		if( is_array( $_GET['cats'] ) ) {
			foreach( $_GET['cats'] as $i )
				$this->flags['categories'][] = intval( $i );
		}
		
		// Get the types(posts, pages, comments) from AdvancedSearch formcategories
		if( is_array( $_GET['types'] ) ) {
			foreach( $_GET['types'] as $i ) {
				$this->flags['types'][] = $wpdb->escape( $i );
			}
		}
		
		// return an array of all the flags/query strings		
		//
		return apply_filters( 'search_flags', $this->flags );
	}
	
	
	
	// Result Search Page
	// This function generates HTML for options to be displayed on a search result page.
	// 
	
	function result_search_page( ) {
		$output = "";

		// Return filters if the feature is enabled. flters are for filtering by content type (posts, pages, comments)
			$option_output = "<br />";
			
			if( is_array( $this->flags['types'] ) ) {
				if( in_array( 'posts', $this->flags['types'] ) )
					$checked['post'] = ' checked="checked"';
					
				if( in_array( 'pages', $this->flags['types'] ) )
					$checked['page'] = ' checked="checked"';
					
				if( in_array( 'comments', $this->flags['types'] ) )
					$checked['comment'] = ' checked="checked"';
			}
			
			// all three types are searched at once
			else {
				$checked['post'] = ' checked="checked"';
				$checked['page'] = ' checked="checked"';
				$checked['comment'] = ' checked="checked"';
			}

		
			// Start building the options output
			$option_output .= __( 'Search Only:' ) . "<input type='checkbox' name='types[]' value='posts'{$checked['post']} /> " . __( 'Posts' ) . "
								 <input type='checkbox' name='types[]' value='pages'{$checked['page']}/> " . __( 'Pages ' ) . "
								 <input type='checkbox' name='types[]' value='comments'{$checked['comment']} /> " . __( 'Comments ') . "<br />";	

		
			$advanced = $this->advanced_link();
		

		// Result Box Output
		$output = "<br /><form method='get' id='resultsearchform' action='' style='text-align: left;'>
		<input type='text' value='" . esc_attr( apply_filters( 'the_search_query', get_search_query() ) ) . "' name='s' id='results' />
		<input type='submit' id='searchsubmit' value='" . __( 'Search' ) . "' />
		{$advanced}
	
		{$option_output}
		</form>";
				
		// FILTER: search_result_box Allows you to make changes to the filter/order box above the search results
		return apply_filters( 'search_result_box', $output );
	}
	

	
	
	// Execute Search
	// This function creates a virtual page and then replaces a shortcode [search] with output from my_search_plugin (the plugin's search() function). This       		// function also outputs all final HTML to the browser for search results.
	//

	function execute_search() {
		global $wpdb, $wp_query;
		
		// Default the loop to nothing since we are trying to overload the page template
		$wp_query->posts = NULL;
		
		// Try to load the search page which SHOULD contain the short code [search]
		$wp_query->posts = $wpdb->get_results( "SELECT * from {$wpdb->prefix}posts WHERE post_type = 'page' and post_title = 'search'" );
		
		// Create a virtual page if the search page does not exist
		if( empty( $wp_query->posts[0] ) ) {
			$object = new stdClass();
			$object->post_title = __( "Search Results :" );
			$object->post_content = "[search]";
			$wp_query->posts[0] = $object;
		
		}
		
		// Parse the short codes for the loop	
		add_shortcode( 'search', array( $this->plugin, 'search' ) );
		
		// Return the template
		$template = get_page_template();
		
		if ( $template ){
			include $template;
		//	echo "templte";
		//	include $template;
			
		}
		else{
		include(TEMPLATEPATH . "/index.php");
			
		//	echo "templatepath";
		}
		exit;
	}
	
}




// Load Search
// This function runs the initialize_search function
// @global object The class object for the above class

function load_search( $query ) {
	global $search_plugin;
	if( $query->is_search )
//	add_filter( 'template_redirect', array( &$search_plugin, 'execute_search' ) );
		$search_plugin->initialize_search();
}

// Load the plugin and call the create_flags function to be used later. This does nothing until WordPress is told to take the object


//
// Load Pugin
// 
// global object The class object for the above class

function load_plugin( ) {
	global $search_plugin;
	$search_plugin = new MyAdvancedSearch();

	if($_GET['advancedsearch'] == "1" ){
		add_filter( 'template_redirect', array( &$search_plugin, 'advanced_search_page' ) );
	}
		add_filter( 'get_search_form', array( &$search_plugin, 'advanced_link' ) );
	
		$search_plugin->plugin->flags = $search_plugin->create_flags();
		add_filter( 'pre_get_posts', 'load_search' );
	
}

add_action( 'plugins_loaded', 'load_plugin' );



//End Class 

// Start Installer Code for pugin

// Plugin Installer
// This function creates the search_index table . 
// 

function plugin_install () {
	global $wpdb;


	$table_name = $wpdb->prefix . "search_index";

 
   // Prepare the create table statement
	if( $wpdb->get_var( "show tables like '{$table_name}'" ) != $table_name ) {
		
		$sql = "CREATE TABLE " . $table_name . " (
			`id` bigint(20) NOT NULL auto_increment,
			`object` bigint(20) NOT NULL,
			`title` text NOT NULL,
			`content` text NOT NULL,
			`post_date` datetime NOT NULL,
			`parent` bigint(20) NOT NULL,
			`categories` text NOT NULL,
			`tags` text NOT NULL,
			`author` text NOT NULL,
			`type` varchar(50) NOT NULL,
			`protected` smallint(6) NOT NULL,
			PRIMARY KEY  (`id`),
			FULLTEXT KEY `title` (`title`),
			FULLTEXT KEY `content` (`content`),
			FULLTEXT KEY `title_and_content` (`title`,`content`)
		) ENGINE MYISAM;";

		// execute the statement	
		require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
		dbDelta( $sql );
		  
		
	}
	

	
	include_once( "myAdvancedSearch.php");
	$index = new search_index();
	$index->refresh_all();
	
}

// End Installer code
	


//Uninstall Plugin deleting table search_index

function plugin_uninstall() {
	global $wpdb;
	
	// Remove the search index
	$wpdb->query( "DROP TABLE {$wpdb->prefix}search_index" );

}


//thigs that ran when pugin is activated
register_activation_hook( __FILE__,'plugin_install' );

//thigs that ran when pugin is deactivated
register_deactivation_hook( __FILE__, 'plugin_uninstall' );





// Start of my_search_plugin Class

class my_search_plugin{

		// Contains an array of MySQL results from a search
		var $results = array();
		
		// An array of search parameters
		var $flags = array();
	
		// Constructor
		
		function my_search_plugin() {

		}

		// This function takes everything from the other plugin and database together. It loads the filter code, calls the results function and outputs the results.
		
		function search(){
		
			// Query the database and format results
			$total = $this->find_results();

				$start = 1;
				
			// Return the results
			if( $total > 0 )
			{
				// FILTER: search_results_start Starts the results output
				$result_html = apply_filters( 'search_results_start', "<ol class=\"searchresults\" start=\"{$start}\">\n" );
				
				foreach( $this->results as $results ) {
					// Result is a post
					if( $results->type == "post" ) {
						// search_post_result Lets you change a single row for result output
						$result_html .= apply_filters( 'search_post_result', "<li><strong class='result_type'>" . __( 'Post ' ) . "</strong>: <a href=\"" . get_permalink( $results->object ) . "\" class='result_title'>" . $results->title . "</a>\n<p class=\"result_summary\"></p></li>" );			
					}
					// Result is a page
					elseif( $results->type == "page" ) {
						// search_page_result Lets you change a single row for result output
						$result_html .= apply_filters( 'search_page_result', "<li><strong class='result_type'>" . __( 'Page ' ) . "</strong>: <a href=\"" . get_permalink ( $results->object ) . "\" class='result_title'>" . $results->title . "</a>\n<p class=\"result_summary\"></p></li>" );
					}
					// Result is a comment
					else {
						// search_comment_result Lets you change a single row for result output
						$result_html .= apply_filters( 'search_comment_result', "<li><strong class='result_type'>" . __( 'Comment ' ) . "</strong>: <a href=\"" . get_comment_link( $results->object ) . "\" class='result_title'>" . get_the_title( $results->parent ) ."</a>\n<p class=\"result_summary\"></p></li>" );
					}
				}
				
				//  search_results_start Ends the results output
				$result_html .= apply_filters( 'search_results_end', "</ol>\n" );
			}
			
			//  If No results 
			else{
				// search_no_results Allows you to change the error message when no results are returned
				$result_html = apply_filters( 'search_no_results', "<h2>" . __( ' There are no results for this search.' ) . "</h2>" );
			}
		
			// Return the search output
			// search_results Allows you to edit the results
			return apply_filters( 'search_results', $this->parent->result_search_page() . $result_html  );
			
		
		}
		
		
		// This function is what physically queries the database and does the search using the flags given from the MyAdvancedSearch
	 // return the number of results
		
		function find_results(){
		
			global $wpdb;				
			if($this->flags['terms'][1] == "and" || $this->flags['terms'][1] == "or"){
			
			if($this->flags['terms'][1] == "and"){
			// Start off our query and our counting of results query	
			
			$start = "SELECT * FROM {$wpdb->prefix}search_index WHERE MATCH ( content,title ) AGAINST('+{$this->flags['terms'][0]} +{$this->flags['terms'][2]}' IN BOOLEAN MODE) ";
			
			$cstart = "SELECT COUNT(*) as total FROM {$wpdb->prefix}search_index WHERE MATCH ( content,title ) AGAINST('+{$this->flags['terms'][0]} +{$this->flags['terms'][2]}' IN BOOLEAN MODE)";
				
			// Add in any date flags
			
		
			
		//	echo $this->flags['terms'][0];
		//	echo $this->flags['terms'][1];
			
			if( !empty( $this->flags['startYear'] ) )
				$sql .= " AND YEAR(post_date) >= " . $this->flags['startYear'];
			if ( !empty( $this->flags['startMonth'] ) )
				$sql .= " AND MONTH(post_date) >= " . $this->flags['startMonth'];
			if ( !empty( $this->flags['startDay'] ) )
				$sql .= " AND DAYOFMONTH(post_date) >= " . $this->flags['startDay'];
		
			if( !empty( $this->flags['endYear'] ) )
				$sql .= " AND YEAR(post_date) <= " . $this->flags['endYear'];		
			if ( !empty( $this->flags['endMonth'] ) )
				$sql .= " AND MONTH(post_date) <= " . $this->flags['endMonth'];
			if ( !empty( $this->flags['endDay'] ) )
				$sql .= " AND DAYOFMONTH(post_date) <= " . $this->flags['endDay'];
	
			
						
			// keep going and do the category flags
			if( is_array( $this->flags['categories'] ) )
			{
				$sql .= " AND (";
 				foreach( $this->flags['categories'] as $category )
				{
					$sql .= " categories LIKE '%,{$category},%' OR ";
				}
				$sql = substr( $sql, 0, -3 ) . ")";
			}
			
			// keep going and do the tags flags
			if( is_array( $this->flags['tags'] ) )
			{
				$sql .= " AND (";
				foreach( $this->flags['tags'] as $tag )
				{
					$sql .= " tags LIKE '%,{$tag},%' OR ";
				}
				$sql = substr( $sql, 0, -3 ) . ")";
			}
			
			// Figure out what type of data we are looking for
			if( is_array( $this->flags['types'] ) ) {
				if( in_array( 'posts', $this->flags['types'] ) && !in_array( 'pages', $this->flags['types'] ) && !in_array( 'comments', $this->flags['types'] ) )
					$sql .= " AND type = 'post'";
				elseif( in_array( 'pages', $this->flags['types'] ) && !in_array( 'posts', $this->flags['types'] ) && !in_array( 'comments', $this->flags['types'] ) )
					$sql .= " AND type = 'page'";
				elseif( in_array( 'comments', $this->flags['types'] ) && !in_array( 'posts', $this->flags['types'] ) && !in_array( 'pages', $this->flags['types'] ) )
					$sql .= " AND type = 'comment'";
				elseif( in_array( 'posts', $this->flags['types'] ) && in_array( 'pages', $this->flags['types'] ) && !in_array( 'comments', $this->flags['types'] ) )
					$sql .= " AND (type = 'post' OR type = 'page')";
				elseif( in_array( 'posts', $this->flags['types'] ) && !in_array( 'pages', $this->flags['types'] ) && in_array( 'comments', $this->flags['types'] ) )
					$sql .= " AND (type = 'post' OR type = 'comment')";
				elseif( !in_array( 'posts', $this->flags['types'] ) && in_array( 'pages', $this->flags['types'] ) && in_array( 'comments', $this->flags['types'] ) )
					$sql .= " AND (type = 'page' OR type = 'comment')";
			}
			
			// How many results do we have total
			$count = $wpdb->get_results( apply_filters( "search_count_find_results", $cstart . $sql ) );
		//	echo $count[0]->total;
	
			// store the results in an array
			$this->results = $wpdb->get_results( apply_filters( "search_find_results", $start . $sql ) );
		//	echo $this->results;
			}
			if($this->flags['terms'][1] == "or"){
			// Start off our query and our counting of results query	
			$start = "SELECT * FROM {$wpdb->prefix}search_index WHERE MATCH ( content,title ) AGAINST('{$this->flags['terms'][0]} {$this->flags['terms'][2]}'IN BOOLEAN MODE ) ";
			//$start = "SELECT * FROM {$wpdb->prefix}search_index WHERE MATCH ( content,title ) AGAINST('{$this->flags[string]}' IN BOOLEAN MODE) ";
			
			$cstart = "SELECT COUNT(*) as total FROM {$wpdb->prefix}search_index  WHERE MATCH ( content,title ) AGAINST('{$this->flags['terms'][0]} {$this->flags['terms'][2]}'IN BOOLEAN MODE ) ";
				
		
			
		//	echo $this->flags['terms'][0];
		//	echo $this->flags['terms'][1];
			
			if( !empty( $this->flags['startYear'] ) )
				$sql .= " AND YEAR(post_date) >= " . $this->flags['startYear'];
			if ( !empty( $this->flags['startMonth'] ) )
				$sql .= " AND MONTH(post_date) >= " . $this->flags['startMonth'];
			if ( !empty( $this->flags['startDay'] ) )
				$sql .= " AND DAYOFMONTH(post_date) >= " . $this->flags['startDay'];
		
			if( !empty( $this->flags['endYear'] ) )
				$sql .= " AND YEAR(post_date) <= " . $this->flags['endYear'];		
			if ( !empty( $this->flags['endMonth'] ) )
				$sql .= " AND MONTH(post_date) <= " . $this->flags['endMonth'];
			if ( !empty( $this->flags['endDay'] ) )
				$sql .= " AND DAYOFMONTH(post_date) <= " . $this->flags['endDay'];
	
		
						
			// keep going and do the category flags
			if( is_array( $this->flags['categories'] ) )
			{
				$sql .= " AND (";
 				foreach( $this->flags['categories'] as $category )
				{
					$sql .= " categories LIKE '%,{$category},%' OR ";
				}
				$sql = substr( $sql, 0, -3 ) . ")";
			}
			
			// keep going and do the tags flags
			if( is_array( $this->flags['tags'] ) )
			{
				$sql .= " AND (";
				foreach( $this->flags['tags'] as $tag )
				{
					$sql .= " tags LIKE '%,{$tag},%' OR ";
				}
				$sql = substr( $sql, 0, -3 ) . ")";
			}
			
			// Figure out what type of data we are looking for
			if( is_array( $this->flags['types'] ) ) {
				if( in_array( 'posts', $this->flags['types'] ) && !in_array( 'pages', $this->flags['types'] ) && !in_array( 'comments', $this->flags['types'] ) )
					$sql .= " AND type = 'post'";
				elseif( in_array( 'pages', $this->flags['types'] ) && !in_array( 'posts', $this->flags['types'] ) && !in_array( 'comments', $this->flags['types'] ) )
					$sql .= " AND type = 'page'";
				elseif( in_array( 'comments', $this->flags['types'] ) && !in_array( 'posts', $this->flags['types'] ) && !in_array( 'pages', $this->flags['types'] ) )
					$sql .= " AND type = 'comment'";
				elseif( in_array( 'posts', $this->flags['types'] ) && in_array( 'pages', $this->flags['types'] ) && !in_array( 'comments', $this->flags['types'] ) )
					$sql .= " AND (type = 'post' OR type = 'page')";
				elseif( in_array( 'posts', $this->flags['types'] ) && !in_array( 'pages', $this->flags['types'] ) && in_array( 'comments', $this->flags['types'] ) )
					$sql .= " AND (type = 'post' OR type = 'comment')";
				elseif( !in_array( 'posts', $this->flags['types'] ) && in_array( 'pages', $this->flags['types'] ) && in_array( 'comments', $this->flags['types'] ) )
					$sql .= " AND (type = 'page' OR type = 'comment')";
			}
			
			// How many results do we have total
			$count = $wpdb->get_results( apply_filters( "search_count_find_results", $cstart . $sql ) );
		
	
			// store the results in an array
			$this->results = $wpdb->get_results( apply_filters( "search_find_results", $start . $sql ) );
			}
			
			}
			
			else{
			// Start off our query and our counting of results query	
			$start = "SELECT * FROM {$wpdb->prefix}search_index WHERE MATCH ( content,title ) AGAINST('{$this->flags[string]}' IN BOOLEAN MODE) ";
		
			$cstart = "SELECT COUNT(*) as total FROM {$wpdb->prefix}search_index WHERE MATCH ( content,title ) AGAINST('{$this->flags[string]}' IN BOOLEAN MODE)";
				
	
		//	echo $this->flags['terms'][0];
		//	echo $this->flags['terms'][1];
			
					// Add in any date flags
			if( !empty( $this->flags['startYear'] ) )
				$sql .= " AND YEAR(post_date) >= " . $this->flags['startYear'];
			if ( !empty( $this->flags['startMonth'] ) )
				$sql .= " AND MONTH(post_date) >= " . $this->flags['startMonth'];
			if ( !empty( $this->flags['startDay'] ) )
				$sql .= " AND DAYOFMONTH(post_date) >= " . $this->flags['startDay'];
		
			if( !empty( $this->flags['endYear'] ) )
				$sql .= " AND YEAR(post_date) <= " . $this->flags['endYear'];		
			if ( !empty( $this->flags['endMonth'] ) )
				$sql .= " AND MONTH(post_date) <= " . $this->flags['endMonth'];
			if ( !empty( $this->flags['endDay'] ) )
				$sql .= " AND DAYOFMONTH(post_date) <= " . $this->flags['endDay'];
			

			
						
			// keep going and do the category flags
			if( is_array( $this->flags['categories'] ) )
			{
				$sql .= " AND (";
 				foreach( $this->flags['categories'] as $category )
				{
					$sql .= " categories LIKE '%,{$category},%' OR ";
				}
				$sql = substr( $sql, 0, -3 ) . ")";
			}
			// keep going and do the tags flags
			if( is_array( $this->flags['tags'] ) )
			{
				$sql .= " AND (";
				foreach( $this->flags['tags'] as $tag )
				{
					$sql .= " tags LIKE '%,{$tag},%' OR ";
				}
				$sql = substr( $sql, 0, -3 ) . ")";
			}
			
			
			
			// Figure out what type of data we are looking for
			if( is_array( $this->flags['types'] ) ) {
				if( in_array( 'posts', $this->flags['types'] ) && !in_array( 'pages', $this->flags['types'] ) && !in_array( 'comments', $this->flags['types'] ) )
					$sql .= " AND type = 'post'";
				elseif( in_array( 'pages', $this->flags['types'] ) && !in_array( 'posts', $this->flags['types'] ) && !in_array( 'comments', $this->flags['types'] ) )
					$sql .= " AND type = 'page'";
				elseif( in_array( 'comments', $this->flags['types'] ) && !in_array( 'posts', $this->flags['types'] ) && !in_array( 'pages', $this->flags['types'] ) )
					$sql .= " AND type = 'comment'";
				elseif( in_array( 'posts', $this->flags['types'] ) && in_array( 'pages', $this->flags['types'] ) && !in_array( 'comments', $this->flags['types'] ) )
					$sql .= " AND (type = 'post' OR type = 'page')";
				elseif( in_array( 'posts', $this->flags['types'] ) && !in_array( 'pages', $this->flags['types'] ) && in_array( 'comments', $this->flags['types'] ) )
					$sql .= " AND (type = 'post' OR type = 'comment')";
				elseif( !in_array( 'posts', $this->flags['types'] ) && in_array( 'pages', $this->flags['types'] ) && in_array( 'comments', $this->flags['types'] ) )
					$sql .= " AND (type = 'page' OR type = 'comment')";
			}
			
			// How many results do we have total
			$count = $wpdb->get_results( apply_filters( "search_count_find_results", $cstart . $sql ) );
		//	echo $count[0]->total;
	
			// store the results in an array
			$this->results = $wpdb->get_results( apply_filters( "search_find_results", $start . $sql ) );
			}
			
			// return the total number of results
			return $count[0]->total;

			}
			
			
}


//Creates The search my_search_plugin object (the class in this file)
	
function load_this_my_search_plugin() {
		return new my_search_plugin();
	}
	
// Tell the above function to run in the MyAdvanced Search 
add_filter('search_load', 'load_this_my_search_plugin' );
	



// End of my_search_plugin Class

//Begin Search Index Class

// This class contains a set of fucntions for updating the search_index teble 
// 
class search_index{


function search_index(){}


function refresh_all() {
		global $wpdb;
		
		// delete the current index	
		$wpdb->query( "DELETE FROM {$wpdb->prefix}search_index" );
	
		// Load all the posts and pages stored within WordPress
		$posts = $wpdb->get_results( "SELECT * from {$wpdb->prefix}posts" );
			
		foreach( $posts as $post ) {
			// don't search revisions
			if( $post->post_type == "page" || $post->post_type == "post" ) {

				// Build a string of categories and tags that this object belongs to
				$cats = ",";
				$tags = ",";
	
				$terms = $wpdb->get_results( "SELECT r.term_taxonomy_id,t.taxonomy,r.object_id from $wpdb->term_relationships r LEFT JOIN $wpdb->term_taxonomy t ON(t.term_taxonomy_id=r.term_taxonomy_id) WHERE r.object_id = '" . intval( $post->ID ) . "'" );
			
				foreach( $terms as $term ) {
					if( $term->taxonomy == "category" )
						$cats .= intval( $term->term_taxonomy_id ) . ",";
					else
						$tags .= intval( $term->term_taxonomy_id ) . ",";
				}
				
				// find the author
				$authors = $wpdb->get_results( "SELECT display_name FROM $wpdb->users WHERE ID = '" . intval( $post->post_author ) . "'" );
				$author = $authors[0]->display_name;			
				
				// Can we search this item?
				if( $post->post_status == "publish" && empty( $post->post_password ) )
					$protected = "0";
				else
					$protected = "1";
		
				// Create the entry in the search index
				$wpdb->query( "INSERT INTO {$wpdb->prefix}search_index (object, title, content, post_date, parent, categories, tags, author, type, protected)
				VALUES (
							  '". intval( $post->ID ) . "', '" . $wpdb->escape( $post->post_title ) . "', '" . $wpdb->escape( $post->post_content ) . "', '" . $wpdb->escape( $post->post_date ) . "', '0', '" . $wpdb->escape( $cats ) . "', '" . $wpdb->escape( $tags ) . "', '" . $wpdb->escape( $author ) . "', '" . $wpdb->escape( $post->post_type ) . "', '" . $wpdb->escape( $protected ) . "'
				);" );
				
				do_action( 'refreshed_search_index' );
			}	
		}
			
		// Load up the comments for insertion now
		$comments = $wpdb->get_results( "SELECT * from {$wpdb->prefix}comments" );
		
		foreach($comments as $comment) {
			// load the post data
			$post = $wpdb->get_results( "SELECT * from {$wpdb->prefix}posts WHERE ID = '" . intval( $comment->comment_post_ID ) . "'" );
			
			// load a string of categories that the comment is in
			$cat = ",";
			$cats = $wpdb->get_results( "SELECT term_taxonomy_id from $wpdb->term_relationships WHERE object_id = '" . intval( $comment->comment_post_ID ) . "'" );
		
			foreach( $cats as $catz ) {
				$cat .= intval( $catz->term_taxonomy_id ) . ","; 
			}
				
			// is the comment searchable
			if( $comment->comment_approved )
				$protected = 0;
			else
				$protected = 1;
			
			// create the search index row
			$wpdb->query( "INSERT INTO {$wpdb->prefix}search_index (object, title, content, post_date, parent, categories, author, type, protected)
					VALUES (
								  '" . intval( $comment->comment_ID ) . "', '', '" . $wpdb->escape( $comment->comment_content ) . "', '" . $wpdb->escape( $comment->comment_date ) . "', '" . intval( $post[0]->ID ) . "', '" . $wpdb->escape( $cat ) . "', '" . $wpdb->escape( $comment->comment_author ) . "', 'comment', '" . $wpdb->escape( $protected ) . "'
					);" );	
		}
		
	}

}


// End Search Index Class





?>
